//
//  SpellSVController.m
//  This file is part of D&D Manager
//
//  Created by Matthew Hutton on 24/05/2006.
//
//
//D&D Manager, a D&D Character and battle management program.
//Copyright (C) 2007, Matthew Hutton
//
//This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License along with this program; if not, write to:
//The Free Software Foundation, Inc.,
//51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
/* SpellSVController */
//Controller for the spell's view for creating and modifying spells.

//file has methods in alphabetical order, rather than grouped by topic, to see if that makes them easier to find.
#import "SpellSVController.h"
#import "SpellMethods.h"
#import "MenuController.h"
#import "MyDocument.h"

@implementation SpellSVController
/*!
 @function init
 */
-(id)init{
	[super init];
	[NSBundle loadNibNamed:@"New Spells View"
					 owner:self];
	divArcOrDom=[[[DivineArcaneOrDomain alloc] init] autorelease];
	divArcOrDomTwo=[[[DivineArcaneOrDomain2 alloc] init] autorelease];
	maxSL=[[[MaxSpellLevel alloc] init] autorelease];
	minSL=[[[MinSpellLevel alloc] init] autorelease];
	[NSValueTransformer setValueTransformer:divArcOrDom
									forName:@"DivineArcaneOrDomain"];
	[NSValueTransformer setValueTransformer:divArcOrDomTwo
									forName:@"DivineArcaneOrDomainTwo"];
	[NSValueTransformer setValueTransformer:maxSL
									forName:@"MaxSpellLevel"];
	[NSValueTransformer setValueTransformer:minSL
									forName:@"MinSpellLevel"];
	[classController setAutomaticallyPreparesContent:NO];
	[classController prepareContent];
	[classController setAutomaticallyPreparesContent:YES];
	[spellController setAutomaticallyPreparesContent:NO];
	[spellController prepareContent];
	[spellController setAutomaticallyPreparesContent:YES];
	[spellClassController setSortDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]]];
	[spellController setSortDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]]];
	return self;
}
/*
 Adds a new spell class object from an 'aClass' derivative.
 */
-(IBAction)addSpellClass:(id)sender{
	//check type of object.
	NSManagedObject *spellClass=[spellClassController newObject];
	//now get the character class object it comes from.
	NSManagedObject *charClass=[[classController selectedObjects] objectAtIndex:0];
	if([[charClass valueForKey:@"divineSpell"] intValue]==-1){
		[spellClass setValue:[NSNumber numberWithBool:YES]
					  forKey:@"domainSpell"];
	}else{
		[spellClass setValue:[NSNumber numberWithBool:NO]
					  forKey:@"domainSpell"];
	}
	[spellClass setValue:charClass
				  forKey:@"aClass"];
	[spellClass setValue:[minSL transformedValue:spellClass]
				  forKey:@"level"];
	[spellClass setValue:[charClass valueForKey:@"name"]
				  forKey:@"name"];
	[spellClassController addObject:spellClass];
	[addClassButton setEnabled:NO];
}
/*
 Adds a new spell and runs appController.setUpBattleStore as required
 */
-(IBAction)addNewSpell:(id)sender{
	NSManagedObject *spell=[spellController newObject];
	[spellController addObject:spell];
	NSString *name=@"Unnamed spell";
	NSArray *array=[spellController arrangedObjects];
	if([[array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"name==\"%@\"",name]]] count]>1){
		BOOL goOn=NO;
		int j=2;
		while(!goOn){
			if([[array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"name==\"%@ #%d\"",name,j]]] count]>0){
				j++;
			}else{
				[spell setValue:[NSString stringWithFormat:@"%@ #%d",name,j] forKey:@"name"];
				goOn=YES;
				break;
			}
		}
	}
	//set up battle store as required.
	[[(MyDocument *)[[NSDocumentController sharedDocumentController] currentDocument] appController] setUpBattleStore];
}
//method run when area type is changed
-(IBAction)areaTypeChanged:(id)sender{
	NSArray *array=[spellController selectedObjects];
	if([array count]==0){
		[areaOfEffectLabel setStringValue:@"length"];
		return;
	}
	NSManagedObject *spell=[array objectAtIndex:0];
	if([[spell valueForKey:@"areaOfEffect"] intValue]==0){
		[areaOfEffectLabel setStringValue:@"radius"];
	}else{
		[areaOfEffectLabel setStringValue:@"length"];
	}
}
//attaches the mainView of this to the tabViewItem presented, also get the window that tabView is resident in and sets it to mainWindow.
-(void)attachMainViewToTabViewItem:(NSTabViewItem *)tvi{
	//NSLog(@"hi");
	[tvi setView:mainView];
	[[(MyDocument *)[[NSDocumentController sharedDocumentController] currentDocument] appController] setUpBattleStore];
	mainWindow=[[tvi tabView] window];
	//NSLog(@"bye");
}
//the casting time is altered.
-(IBAction)castingTimeChanged:(id)sender{
	NSArray *array=[spellController selectedObjects];
	if([array count]==0){
		[castingTimeCustom setBackgroundColor:[NSColor colorWithDeviceRed:0.93
																	green:0.93
																	 blue:0.93
																	alpha:1.0]];
		
		[castingTimeCustom setEnabled:NO];
		return;
	}
	NSManagedObject *spell=[array objectAtIndex:0];
	if([[spell valueForKey:@"castingTime"] intValue]==3){
		[castingTimeCustom setEnabled:YES];
		[castingTimeCustom setBackgroundColor:[NSColor whiteColor]];
	}else{
		[castingTimeCustom setBackgroundColor:[NSColor colorWithDeviceRed:0.93
																	green:0.93
																	 blue:0.93
																	alpha:1.0]];
		
		[castingTimeCustom setEnabled:NO];
	}
}
-(void)characterClassSheetDidEnd:(NSWindow *)sheet
					  returnCode:(int)returnCode
					 contextInfo:(void *)contextInfo{
	[self displayAddSpellClassSheet:nil];
}
-(IBAction)characterMagicScreen:(id)sender{
	MyDocument *currentDocument=(MyDocument *)[[NSDocumentController sharedDocumentController] currentDocument];
	if(currentDocument==nil){
		currentDocument=(MyDocument *)[[NSApp orderedDocuments] objectAtIndex:0];
		if(currentDocument==nil){
			NSLog(@"currentDocument playing up, and order docs playing up too.");
			NSBeep();
			return;
		}
	}
	[[currentDocument appController] characterMagicScreen:nil];
}
/*
 Closes the AddClass Sheet
 */
-(IBAction)closeAddClassSheet:(id)sender{
	[addClassSheet orderOut:sender];
	[NSApp endSheet:addClassSheet];
}
/*
 Closes the damage alteration sheet.
 */
-(IBAction)closeDamageBox:(id)sender{
	if([[spellController selectedObjects] count]==0){
		return;
	}
	[damageSheet orderOut:self];
	[NSApp endSheet:damageSheet];
	//create description.
	NSString *str=@"";
	NSObject *spell=[[spellController selectedObjects] objectAtIndex:0];
	//get dice per level
	if([[spell valueForKey:@"damLvlNoOfDie"] intValue]!=0){
		str=[[NSString alloc] initWithFormat:@"%@d%@",[spell valueForKey:@"damLvlNoOfDie"],[spell valueForKey:@"damLvlSizeOfDie"]];
	}
	//get bonus per level.
	if([[spell valueForKey:@"damLvlBonus"] intValue]!=0){
		if([str isEqualToString:@""]){
			str=[[NSString alloc] initWithFormat:@"%@",[spell valueForKey:@"damLvlBonus"]];
		}else{
			str=[[NSString alloc] initWithFormat:@"%@+%@",str,[spell valueForKey:@"damLvlBonus"]];
		}
	}
	//check if any content
	if(![str isEqualToString:@""]){
		//gets the rate of increase
		int noOfLvls=[[spell valueForKey:@"damPerLvls"] intValue];
		if(noOfLvls==1){
			str=[[NSString alloc] initWithFormat:@"%@/level ",str];
		}else{
			str=[[NSString alloc] initWithFormat:@"%@/%d levels ",str,noOfLvls];
		}
		//try to get maximum.
		NSString *str2=@"";
		if([[spell valueForKey:@"damMaxNoOfDie"] intValue]!=0){
			str2=[[NSString alloc] initWithFormat:@"%@d%@",[spell valueForKey:@"damMaxNoOfDie"],[spell valueForKey:@"damLvlSizeOfDie"]];
		}
		if([[spell valueForKey:@"damMaxBonus"] intValue]!=0){
			if([str2 isEqualToString:@""]){
				str2=[[NSString alloc] initWithFormat:@"%@",[spell valueForKey:@"damMaxBonus"]];
			}else{
				str2=[[NSString alloc] initWithFormat:@"%@+%@",str2,[spell valueForKey:@"damMaxBonus"]];
			}
		}
		if(![str2 isEqualToString:@""]){
			str=[[NSString alloc] initWithFormat:@"%@(max. %@)",str,str2];
		}
	}
	//add on the fixed bonus.
	NSString *str2=@"";
	if([[spell valueForKey:@"damBonNoOfDie"] intValue]!=0){
		str2=[[NSString alloc] initWithFormat:@"%@d%@ ",[spell valueForKey:@"damBonNoOfDie"],[spell valueForKey:@"damBonSizeOfDie"]];
	}
	if([[spell valueForKey:@"damBonBonus"] intValue]!=0){
		if([str2 isEqualToString:@""]){
			str2=[[NSString alloc] initWithFormat:@"%@",[spell valueForKey:@"damBonBonus"]];
		}else{
			str2=[[NSString alloc] initWithFormat:@"%@+%@",str2,[spell valueForKey:@"damBonBonus"]];
		}
	}
	if(![str2 isEqualToString:@""]){
		if([str isEqualToString:@""]){
			str=str2;
		}else{
			str=[[NSString alloc] initWithFormat:@"%@ + %@",str,str2];
		}
	}
	if([str isEqualToString:@""]){
		[spell setValue:@"None"
				 forKey:@"damDescription"];
	}else{
		[spell setValue:str
				 forKey:@"damDescription"];
	}
}
/*
 Closes the duration sheet
 */
-(IBAction)closeDurationBox:(id)sender{
	if([[spellController selectedObjects] count]==0){
		return;
	}
	[durationSheet orderOut:self];
	[NSApp endSheet:durationSheet];
	//create description.
	NSString *str=@"";
	NSObject *spell=[[spellController selectedObjects] objectAtIndex:0];
	//check measurement unit.
	NSString *measuredIn;
	if([[spell valueForKey:@"durMeasuredIn"] intValue]==0){
		measuredIn=@"rounds";
	}else if([[spell valueForKey:@"durMeasuredIn"] intValue]==1){
		measuredIn=@"minutes";
	}else if([[spell valueForKey:@"durMeasuredIn"] intValue]==2){
		measuredIn=@"hours";
	}else if([[spell valueForKey:@"durMeasuredIn"] intValue]==3){
		measuredIn=@"days";
	}
	//get dice per level
	if([[spell valueForKey:@"durLvlNoOfDie"] intValue]!=0){
		str=[[NSString alloc] initWithFormat:@"%@d%@",[spell valueForKey:@"durLvlNoOfDie"],[spell valueForKey:@"durLvlSizeOfDie"]];
	}
	//get bonus per level.
	if([[spell valueForKey:@"durLvlBonus"] intValue]!=0){
		if([str isEqualToString:@""]){
			str=[[NSString alloc] initWithFormat:@"%@",[spell valueForKey:@"durLvlBonus"]];
		}else{
			str=[[NSString alloc] initWithFormat:@"%@+%@",str,[spell valueForKey:@"durLvlBonus"]];
		}
	}
	//check if any content
	if(![str isEqualToString:@""]){
		//gets the rate of increase
		int noOfLvls=[[spell valueForKey:@"durPerLvls"] intValue];
		if(noOfLvls==1){
			str=[[NSString alloc] initWithFormat:@"%@ %@/level ",str,measuredIn];
		}else{
			str=[[NSString alloc] initWithFormat:@"%@ %@/%d levels ",str,measuredIn,noOfLvls];
		}
		//try to get maximum.
		NSString *str2=@"";
		if([[spell valueForKey:@"durMaxNoOfDie"] intValue]!=0){
			str2=[[NSString alloc] initWithFormat:@"%@d%@",[spell valueForKey:@"durMaxNoOfDie"],[spell valueForKey:@"durLvlSizeOfDie"]];
		}
		if([[spell valueForKey:@"durMaxBonus"] intValue]!=0){
			if([str2 isEqualToString:@""]){
				str2=[[NSString alloc] initWithFormat:@"%@",[spell valueForKey:@"durMaxBonus"]];
			}else{
				str2=[[NSString alloc] initWithFormat:@"%@+%@",str2,[spell valueForKey:@"durMaxBonus"]];
			}
		}
		if(![str2 isEqualToString:@""]){
			str=[[NSString alloc] initWithFormat:@"%@(max. %@ %@)",str,str2,measuredIn];
		}
	}
	//add on the fixed bonus.
	NSString *str2=@"";
	if([[spell valueForKey:@"durBonNoOfDie"] intValue]!=0){
		str2=[[NSString alloc] initWithFormat:@"%@d%@ ",[spell valueForKey:@"durBonNoOfDie"],[spell valueForKey:@"durBonSizeOfDie"]];
	}
	if([[spell valueForKey:@"durBonBonus"] intValue]!=0){
		if([str2 isEqualToString:@""]){
			str2=[[NSString alloc] initWithFormat:@"%@",[spell valueForKey:@"durBonBonus"]];
		}else{
			str2=[[NSString alloc] initWithFormat:@"%@+%@",str2,[spell valueForKey:@"durBonBonus"]];
		}
	}
	if(![str2 isEqualToString:@""]){
		if([str isEqualToString:@""]){
			str=[[NSString alloc] initWithFormat:@"%@ %@",str2,measuredIn];
		}else{
			str=[[NSString alloc] initWithFormat:@"%@ + %@ %@",str,str2,measuredIn];
		}
	}
	//add Conc bonus.
	if([[spell valueForKey:@"durForConc"] boolValue]){
		if([str isEqualToString:@""]){
			str=@"concentration ";
		}else{
			str=[[NSString alloc] initWithFormat:@"%@+conc. ",str];
		}
		if([[spell valueForKey:@"durMaxConc"] intValue]!=0){
			str=[[NSString alloc] initWithFormat:@"%@(max. %@ %@) ",str,[spell valueForKey:@"durMaxConc"],measuredIn];
		}
	}
	if(![str isEqualToString:@""] && [[spell valueForKey:@"durInstantaneous"] boolValue]){
		[spell setValue:[NSNumber numberWithBool:NO]
				 forKey:@"durInstantaneous"];
	}
	//check for dischargable.
	if([[spell valueForKey:@"durDischarge"] boolValue]){
		str=[[NSString alloc] initWithFormat:@"%@ (D)",str];
	}
	if([[spell valueForKey:@"durInstantaneous"] boolValue]){
		[spell setValue:@"Instantaneous"
				 forKey:@"durDescription"];
		//[durationDescription setStringValue:@"Instantaneous"];
	}else if([[spell valueForKey:@"durPermanent"] boolValue]){
		[spell setValue:@"Permanent"
				 forKey:@"durDescription"];
	}else{
		[spell setValue:str
				 forKey:@"durDescription"];
		//[durationDescription setStringValue:str];
	}
}
/*
 Closes the feats box
 */
-(IBAction)closeFeatBox:(id)sender{
	NSManagedObject *spell=[[spellController selectedObjects] objectAtIndex:0];
	[SpellMethods processFeatDescriptionForSpell:spell];
	[featSheet orderOut:sender];
	[NSApp endSheet:featSheet];
}
/*
 Closes the number of attacks sheet
 */
-(IBAction)closeNoOfAttacksBox:(id)sender{
	if([[spellController selectedObjects] count]==0){
		return;
	}
	[noOfAttacksSheet orderOut:self];
	[NSApp endSheet:noOfAttacksSheet];
	//create description.
	NSString *str=@"";
	NSObject *spell=[[spellController selectedObjects] objectAtIndex:0];
	//get dice per level
	if([[spell valueForKey:@"noaLvlNoOfDie"] intValue]!=0){
		str=[[NSString alloc] initWithFormat:@"%@d%@",[spell valueForKey:@"noaLvlNoOfDie"],[spell valueForKey:@"noaLvlSizeOfDie"]];
	}
	//get bonus per level.
	if([[spell valueForKey:@"noaLvlBonus"] intValue]!=0){
		if([str isEqualToString:@""]){
			str=[[NSString alloc] initWithFormat:@"%@",[spell valueForKey:@"noaLvlBonus"]];
		}else{
			str=[[NSString alloc] initWithFormat:@"%@+%@",str,[spell valueForKey:@"noaLvlBonus"]];
		}
	}
	//check if any content
	if(![str isEqualToString:@""]){
		//gets the rate of increase
		int noOfLvls=[[spell valueForKey:@"noaPerLvls"] intValue];
		if(noOfLvls==1){
			str=[[NSString alloc] initWithFormat:@"%@/level ",str];
		}else{
			str=[[NSString alloc] initWithFormat:@"%@/%d levels ",str,noOfLvls];
		}
		//try to get maximum.
		NSString *str2=@"";
		if([[spell valueForKey:@"noaMaxNoOfDie"] intValue]!=0){
			str2=[[NSString alloc] initWithFormat:@"%@d%@",[spell valueForKey:@"noaMaxNoOfDie"],[spell valueForKey:@"noaLvlSizeOfDie"]];
		}
		if([[spell valueForKey:@"noaMaxBonus"] intValue]!=0){
			if([str2 isEqualToString:@""]){
				str2=[[NSString alloc] initWithFormat:@"%@",[spell valueForKey:@"noaMaxBonus"]];
			}else{
				str2=[[NSString alloc] initWithFormat:@"%@+%@",str2,[spell valueForKey:@"noaMaxBonus"]];
			}
		}
		if(![str2 isEqualToString:@""]){
			str=[[NSString alloc] initWithFormat:@"%@(max. %@)",str,str2];
		}
	}
	//add on the fixed bonus.
	NSString *str2=@"";
	if([[spell valueForKey:@"noaBonNoOfDie"] intValue]!=0){
		str2=[[NSString alloc] initWithFormat:@"%@d%@ ",[spell valueForKey:@"noaBonNoOfDie"],[spell valueForKey:@"noaBonSizeOfDie"]];
	}
	if([[spell valueForKey:@"noaBonBonus"] intValue]!=0){
		if([str2 isEqualToString:@""]){
			str2=[[NSString alloc] initWithFormat:@"%@",[spell valueForKey:@"noaBonBonus"]];
		}else{
			str2=[[NSString alloc] initWithFormat:@"%@+%@",str2,[spell valueForKey:@"noaBonBonus"]];
		}
	}
	if(![str2 isEqualToString:@""]){
		if([str isEqualToString:@""]){
			str=str2;
		}else{
			str=[[NSString alloc] initWithFormat:@"%@ + %@",str,str2];
		}
	}
	if([str isEqualToString:@""]){
		[spell setValue:@"None"
				 forKey:@"noaDesc"];
	}else{
		[spell setValue:str
				 forKey:@"noaDesc"];
	}
}
/*
 Closes the range sheet
 */
-(IBAction)closeRangeBox:(id)sender{
	[rangeSheet orderOut:self];
	[NSApp endSheet:rangeSheet];
	if([[spellController selectedObjects] count]==0){
		NSLog(@"no spell selected");
		return;
	}
	//NSLog(@"hi!");
	//check whether a pre-defined range has been chosen.
	NSManagedObject *spell=[[spellController selectedObjects] objectAtIndex:0];
	[SpellMethods processRangeDescriptionForSpell:spell];
}
-(IBAction)continueBattle:(id)sender{
	[exitButton setEnabled:NO];
	[continueButton setEnabled:NO];
	[(MenuController *)[NSApp delegate] continueBattle:nil];
}
/*
 displays the addSpellClass sheet and sets up the sheet too.
 */
-(IBAction)displayAddSpellClassSheet:(id)sender{
	[classController setAutomaticallyPreparesContent:NO];
	[classController prepareContent];
	[classController setAutomaticallyPreparesContent:YES];
	[classController setSortDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]]];
	if(![classController canRemove]){
		[addClassButton setEnabled:NO];
	}
	[NSApp beginSheet:addClassSheet
	   modalForWindow:mainWindow
		modalDelegate:self
	   didEndSelector:nil
		  contextInfo:NULL];
}
/*
 Display's the damage sheet
 */
-(IBAction)displayDamageBox:(id)sender{
	[NSApp beginSheet:damageSheet
	   modalForWindow:mainWindow
		modalDelegate:self
	   didEndSelector:nil
		  contextInfo:NULL];
}
/*
 Display's the duration sheet
 */
-(IBAction)displayDurationBox:(id)sender{
	[NSApp beginSheet:durationSheet
	   modalForWindow:mainWindow
		modalDelegate:self
	   didEndSelector:nil
		  contextInfo:NULL];
}
/*
 Display's the "feats" sheet for spells.
 */
-(IBAction)displayFeatBox:(id)sender{
	[self spellAbilityChosen:nil];
	[NSApp beginSheet:featSheet
	   modalForWindow:mainWindow
		modalDelegate:self
	   didEndSelector:nil
		  contextInfo:NULL];
}
/*
 Display's the number of attacks sheet
 */
-(IBAction)displayNoOfAttacksBox:(id)sender{
	[NSApp beginSheet:noOfAttacksSheet
	   modalForWindow:mainWindow
		modalDelegate:self
	   didEndSelector:nil
		  contextInfo:NULL];
}
/*
 displays range box if required, otherwise just sets up values.
 */
-(IBAction)displayRangeBox:(id)sender{
	if([[spellController selectedObjects] count]==0){
		return;
	}
	//NSLog(@"hi!");
	//check whether a pre-defined range has been chosen.
	NSManagedObject *spell=[[spellController selectedObjects] objectAtIndex:0];
	[spell setValue:[sender title]
			 forKey:@"range"];
	//NSLog(@"spell range value=%@",[spell valueForKey:@"range"]);
	if([[spell valueForKey:@"range"] isEqualToString:@"Personal"] || [[spell valueForKey:@"range"] isEqualToString:@"Touch"]){
		[spell setValue:nil
				 forKey:@"ranLvlNoOfDie"];
		[spell setValue:nil
				 forKey:@"ranLvlSizeOfDie"];
		[spell setValue:nil
				 forKey:@"ranLvlBonus"];
		[spell setValue:nil
				 forKey:@"ranMaxNoOfDie"];
		[spell setValue:nil
				 forKey:@"ranMaxBonus"];
		[spell setValue:nil
				 forKey:@"ranBonNoOfDie"];
		[spell setValue:nil
				 forKey:@"ranBonSizeOfDie"];
		[spell setValue:nil
				 forKey:@"ranBonBonus"];
		[spell setValue:nil
				 forKey:@"ranPerLvls"];
		[spell setValue:[NSNumber numberWithInt:0]
				 forKey:@"ranMeasuredIn"];
		//no change required.
	}else if([[spell valueForKey:@"range"] isEqualToString:@"Close"]){
		[spell setValue:nil
				 forKey:@"ranLvlNoOfDie"];
		[spell setValue:nil
				 forKey:@"ranLvlSizeOfDie"];
		[spell setValue:[NSNumber numberWithInt:5]
				 forKey:@"ranLvlBonus"];
		[spell setValue:nil
				 forKey:@"ranMaxNoOfDie"];
		[spell setValue:nil
				 forKey:@"ranMaxBonus"];
		[spell setValue:nil
				 forKey:@"ranBonNoOfDie"];
		[spell setValue:nil
				 forKey:@"ranBonSizeOfDie"];
		[spell setValue:[NSNumber numberWithInt:25]
				 forKey:@"ranBonBonus"];
		[spell setValue:[NSNumber numberWithInt:2]
				 forKey:@"ranPerLvls"];
		[spell setValue:[NSNumber numberWithInt:0]
				 forKey:@"ranMeasuredIn"];
	}else if([[spell valueForKey:@"range"] isEqualToString:@"Medium"]){
		[spell setValue:nil
				 forKey:@"ranLvlNoOfDie"];
		[spell setValue:nil
				 forKey:@"ranLvlSizeOfDie"];
		[spell setValue:[NSNumber numberWithInt:10]
				 forKey:@"ranLvlBonus"];
		[spell setValue:nil
				 forKey:@"ranMaxNoOfDie"];
		[spell setValue:nil
				 forKey:@"ranMaxBonus"];
		[spell setValue:nil
				 forKey:@"ranBonNoOfDie"];
		[spell setValue:nil
				 forKey:@"ranBonSizeOfDie"];
		[spell setValue:[NSNumber numberWithInt:100]
				 forKey:@"ranBonBonus"];
		[spell setValue:[NSNumber numberWithInt:1]
				 forKey:@"ranPerLvls"];
		[spell setValue:[NSNumber numberWithInt:0]
				 forKey:@"ranMeasuredIn"];
	}else if([[spell valueForKey:@"range"] isEqualToString:@"Long"]){
		[spell setValue:nil
				 forKey:@"ranLvlNoOfDie"];
		[spell setValue:nil
				 forKey:@"ranLvlSizeOfDie"];
		[spell setValue:[NSNumber numberWithInt:40]
				 forKey:@"ranLvlBonus"];
		[spell setValue:nil
				 forKey:@"ranMaxNoOfDie"];
		[spell setValue:nil
				 forKey:@"ranMaxBonus"];
		[spell setValue:nil
				 forKey:@"ranBonNoOfDie"];
		[spell setValue:nil
				 forKey:@"ranBonSizeOfDie"];
		[spell setValue:[NSNumber numberWithInt:400]
				 forKey:@"ranBonBonus"];
		[spell setValue:[NSNumber numberWithInt:1]
				 forKey:@"ranPerLvls"];
		[spell setValue:[NSNumber numberWithInt:0]
				 forKey:@"ranMeasuredIn"];
	}
	if([[spell valueForKey:@"range"] isEqualToString:@"Custom"]){
		//NSLog(@"loading sheet");
		[NSApp beginSheet:rangeSheet
		   modalForWindow:mainWindow
			modalDelegate:self
		   didEndSelector:nil
			  contextInfo:NULL];
	}else{
		//NSLog(@"processing r description");
		[SpellMethods processRangeDescriptionForSpell:spell];
	}
	//NSLog(@"finished");
}
//nils other values if instantaneous or permanent are switched on.
-(IBAction)durInstantaneousOrPermanentChanged:(id)sender{
	if([sender state]==NSOnState){
		if([[spellController selectedObjects] count]==0){
			//NSLog(@"error, no spell selected SpellController l50");
		}
		//switch on, remove other values.
		NSManagedObject *spell=[[spellController selectedObjects] objectAtIndex:0];
		[spell setValue:nil
				 forKey:@"durBonBonus"];
		[spell setValue:nil
				 forKey:@"durBonNoOfDie"];
		[spell setValue:nil
				 forKey:@"durBonSizeOfDie"];
		[spell setValue:nil
				 forKey:@"durLvlBonus"];
		[spell setValue:nil
				 forKey:@"durLvlNoOfDie"];
		[spell setValue:nil
				 forKey:@"durLvlSizeOfDie"];
		[spell setValue:nil
				 forKey:@"durMaxBonus"];
		[spell setValue:nil
				 forKey:@"durMaxNoOfDie"];
		[spell setValue:nil
				 forKey:@"durMaxSizeOfDie"];
		[spell setValue:[NSNumber numberWithBool:NO]
				 forKey:@"durDischarge"];
		[spell setValue:[NSNumber numberWithBool:NO]
				 forKey:@"durForConc"];
		[spell setValue:nil
				 forKey:@"durMaxConc"];
	}else{
		//going off, do nothing.
	}
}
-(IBAction)editDomainChoices:(id)sender{
	[(MenuController *)[NSApp delegate] showPreferences:nil];
}
/*
 *Allows you to edit the character class choices
 */
-(IBAction)editCharacterClassChoices:(id)sender{
	[addClassSheet orderOut:sender];
	[NSApp endSheet:addClassSheet];
	if(ccController==nil){
		ccController=[[CharacterClassController alloc] init];
	}
	[ccController setCloseButtonName:@"Return"];
	[NSApp beginSheet:[ccController ccWindow]
	   modalForWindow:mainWindow
		modalDelegate:self
	   didEndSelector:@selector(characterClassSheetDidEnd:returnCode:contextInfo:)
		  contextInfo:NULL];
}
-(IBAction)exitBattle:(id)sender{
	[exitButton setEnabled:NO];
	[continueButton setEnabled:NO];
	[(MenuController *)[NSApp delegate] exitBattle:nil];
}
//returns the NSManagedObjectContext.
-(NSManagedObjectContext *)managedObjectContext{
	if(mObjC==nil){
		mObjC=[[[NSDocumentController sharedDocumentController] currentDocument] managedObjectContext];
	}
	//return 
	return mObjC;
}
//saving throw type changed.
-(IBAction)savingThrowTypeChanged:(id)sender{
	NSArray *array=[spellController selectedObjects];
	if([array count]==0){
		[saveEffect setEnabled:NO];
		return;
	}
	NSManagedObject *spell=[array objectAtIndex:0];
	if([[spell valueForKey:@"saveType"] intValue]==4){
		[saveEffect setEnabled:NO];
	}else{
		[saveEffect setEnabled:YES];
	}
	
}
-(void)setUpBattleButtons:(BOOL)nowAreOn{
	[exitButton setEnabled:nowAreOn];
	[continueButton setEnabled:nowAreOn];
}
-(void)setupSpellSubTypeForSpell:(NSManagedObject *)spell{
	if([damageOrFeatOrNeither numberOfTabViewItems]==1){
		NSString *newType=[[damageOrFeatOrNeither selectedTabViewItem] label];
		if([newType isEqualToString:@"None"] || [newType isEqualToString:@"Neither"] || [newType isEqualToString:@"Summoning"]){
			[spell setValue:@"Neither"
					 forKey:@"subtype"];
		}else{
			[spell setValue:newType
					 forKey:@"subtype"];
		}
	}else{
		NSString *subtype=[spell valueForKey:@"subtype"];
		//NSLog(@"subtype=%@",subtype);
		int i;
		BOOL valueFound=NO;
		for(i=0;i<[damageOrFeatOrNeither numberOfTabViewItems];i++){
			if([[[damageOrFeatOrNeither tabViewItemAtIndex:i] label] isEqualToString:subtype]){
				[damageOrFeatOrNeither selectTabViewItemAtIndex:i];
				valueFound=YES;
				break;
			}
		}
		if(!valueFound){
			[spell setValue:[[damageOrFeatOrNeither tabViewItemAtIndex:0] label]
					 forKey:@"subtype"];
			[damageOrFeatOrNeither selectTabViewItemAtIndex:0];
		}
	}
}
-(IBAction)showRollDiceScreen:(id)sender{
	[(MenuController *)[NSApp delegate] rollDice:nil];
}
-(IBAction)showImportSpellsScreen:(id)sender{
	[(MenuController *)[NSApp delegate] import:nil];
}
//method disables/enables controls for hasted/slowed.
-(IBAction)spellAbilityChosen:(id)sender{
	if([[spellAbilKey1 titleOfSelectedItem] isEqualToString:@"Hasted"] || [[spellAbilKey1 titleOfSelectedItem] isEqualToString:@"Slowed"]){
		//[spellAbilDie1 setEnabled:NO];
		[spellAbilFixed1 setEnabled:NO];
	}else{
		//[spellAbilDie1 setEnabled:YES];
		[spellAbilFixed1 setEnabled:YES];
	}
	if([[spellAbilKey2 titleOfSelectedItem] isEqualToString:@"Hasted"] || [[spellAbilKey2 titleOfSelectedItem] isEqualToString:@"Slowed"]){
		//[spellAbilDie2 setEnabled:NO];
		[spellAbilFixed2 setEnabled:NO];
	}else{
		//[spellAbilDie2 setEnabled:YES];
		[spellAbilFixed2 setEnabled:YES];
	}
	if([[spellAbilKey3 titleOfSelectedItem] isEqualToString:@"Hasted"] || [[spellAbilKey3 titleOfSelectedItem] isEqualToString:@"Slowed"]){
		//[spellAbilDie3 setEnabled:NO];
		[spellAbilFixed3 setEnabled:NO];
	}else{
		//[spellAbilDie3 setEnabled:YES];
		[spellAbilFixed3 setEnabled:YES];
	}
	if([[spellAbilKey4 titleOfSelectedItem] isEqualToString:@"Hasted"] || [[spellAbilKey4 titleOfSelectedItem] isEqualToString:@"Slowed"]){
		//[spellAbilDie4 setEnabled:NO];
		[spellAbilFixed4 setEnabled:NO];
	}else{
		//[spellAbilDie4 setEnabled:YES];
		[spellAbilFixed4 setEnabled:YES];
	}
}
//method run when spell affect changed, so creature box can be enabled/disabled.
-(IBAction)spellAffectsChanged:(id)sender{
	NSArray *array=[spellController selectedObjects];
	if([array count]==0){
		[characterTypeAffected setEnabled:NO];
		return;
	}
	NSManagedObject *spell=[array objectAtIndex:0];
	if([[spell valueForKey:@"spellAffects"] intValue]==0){
		[characterTypeAffected setEnabled:NO];
	}else{
		[characterTypeAffected setEnabled:YES];
	}
}
-(IBAction)spellSubtypeChanged:(id)sender{
	NSArray *array=[spellController selectedObjects];
	if([array count]==0){
		return;
	}
	NSManagedObject *spell=[array objectAtIndex:0];
	NSString *newType=[[damageOrFeatOrNeither selectedTabViewItem] label];
	//NSLog(@"newType=%@",newType);
	if([newType isEqualToString:@"None"] || [newType isEqualToString:@"Neither"] || [newType isEqualToString:@"Summoning"]){
		[spell setValue:@"Neither"
				 forKey:@"subtype"];
	}else{
		[spell setValue:newType
				 forKey:@"subtype"];
	}
}
//method run when spell type value is changed.
-(IBAction)spellTypeChanged:(id)sender{
	[damageOrFeatOrNeither setDelegate:nil];
	NSArray *array=[spellController selectedObjects];
	if([array count]==0){
		[attackRollRequired setEnabled:NO];
		[paralysesTargets setEnabled:NO];
		[targetsChangeEachRound setEnabled:NO];
		[returnToCharacterScreen setEnabled:NO];
		[spellResistance setEnabled:NO];
		[spellAffects setEnabled:NO];
		[characterTypeAffected setEnabled:NO];
		int i;
		for(i=0;i<[damageOrFeatOrNeither numberOfTabViewItems]-1;i++){
			[damageOrFeatOrNeither removeTabViewItem:[damageOrFeatOrNeither tabViewItemAtIndex:1]];
		}
		[damageOrFeatOrNeither selectTabViewItemAtIndex:0];
		NSTabViewItem *tvi=[damageOrFeatOrNeither tabViewItemAtIndex:0];
		[tvi setLabel:@"None"];
		[tvi setView:neitherView];
		return;
	}
	NSManagedObject *spell=[array objectAtIndex:0];
	if([[spell valueForKey:@"type"] intValue]==0){
		int i;
		int total=[damageOrFeatOrNeither numberOfTabViewItems];
		for(i=0;i<total-1;i++){
			[damageOrFeatOrNeither removeTabViewItem:[damageOrFeatOrNeither tabViewItemAtIndex:1]];
		}
		[damageOrFeatOrNeither selectTabViewItemAtIndex:0];
		NSTabViewItem *tvi=[damageOrFeatOrNeither tabViewItemAtIndex:0];
		[tvi setLabel:@"Healing"];
		[tvi setView:healingView];
		//changing relevant buttons.
		[attackRollRequired setEnabled:NO];
		[paralysesTargets setEnabled:NO];
		[targetsChangeEachRound setEnabled:YES];
		[returnToCharacterScreen setEnabled:YES];
		[spellResistance setEnabled:YES];
		[spellAffects setEnabled:YES];
		[self spellAffectsChanged:nil];
	}else{
		if([[spell valueForKey:@"type"] intValue]==3){
			//summoning.
			int i;
			int total=[damageOrFeatOrNeither numberOfTabViewItems];
			for(i=0;i<total-1;i++){
				[damageOrFeatOrNeither removeTabViewItem:[damageOrFeatOrNeither tabViewItemAtIndex:1]];
			}
			[damageOrFeatOrNeither selectTabViewItemAtIndex:0];
			NSTabViewItem *tvi=[damageOrFeatOrNeither tabViewItemAtIndex:0];
			[tvi setLabel:@"Summoning"];
			[tvi setView:neitherView];
			//changing relevant buttons.
			[attackRollRequired setEnabled:NO];
			[paralysesTargets setEnabled:NO];
			[targetsChangeEachRound setEnabled:NO];
			[returnToCharacterScreen setState:1];
			[returnToCharacterScreen setEnabled:NO];
			[spellResistance setState:0];
			[spellResistance setEnabled:NO];
			[spellAffects setEnabled:NO];
			[characterTypeAffected setEnabled:NO];
		}else{
			if([[spell valueForKey:@"type"] intValue]==1){
				int i;
				int total=[damageOrFeatOrNeither numberOfTabViewItems];
				for(i=0;i<total-1;i++){
					[damageOrFeatOrNeither removeTabViewItem:[damageOrFeatOrNeither tabViewItemAtIndex:1]];
				}
				[damageOrFeatOrNeither selectTabViewItemAtIndex:0];
				NSTabViewItem *tvi=[damageOrFeatOrNeither tabViewItemAtIndex:0];
				[tvi setLabel:@"Damage"];
				[tvi setView:damageView];
			}else if([[spell valueForKey:@"type"] intValue]==4){
				int i;
				int total=[damageOrFeatOrNeither numberOfTabViewItems];
				for(i=0;i<total-1;i++){
					[damageOrFeatOrNeither removeTabViewItem:[damageOrFeatOrNeither tabViewItemAtIndex:1]];
				}
				[damageOrFeatOrNeither selectTabViewItemAtIndex:0];
				NSTabViewItem *tvi=[damageOrFeatOrNeither tabViewItemAtIndex:0];
				[tvi setLabel:@"None"];
				[tvi setView:neitherView];
			}else{
				int i;
				int total=[damageOrFeatOrNeither numberOfTabViewItems];
				for(i=0;i<3-total;i++){
					NSTabViewItem *tabViewItem=[[[NSTabViewItem alloc] init] autorelease];
					[damageOrFeatOrNeither addTabViewItem:tabViewItem];
				}
				NSTabViewItem *tvi=[damageOrFeatOrNeither tabViewItemAtIndex:0];
				[tvi setLabel:@"Damage"];
				[tvi setView:damageView];
				tvi=[damageOrFeatOrNeither tabViewItemAtIndex:1];
				[tvi setLabel:@"Feat"];
				[tvi setView:featView];
				tvi=[damageOrFeatOrNeither tabViewItemAtIndex:2];
				[tvi setLabel:@"Neither"];
				[tvi setView:neitherView];
			}
			[attackRollRequired setEnabled:YES];
			[paralysesTargets setEnabled:YES];
			[targetsChangeEachRound setEnabled:YES];
			[returnToCharacterScreen setEnabled:YES];
			[spellResistance setEnabled:YES];
			[spellAffects setEnabled:YES];
			[self spellAffectsChanged:nil];
			if([[spell valueForKey:@"subtype"] isEqualToString:@""]){
				[spell setValue:@"Damage"
						 forKey:@"subtype"];
			}
		}
	}
	[damageOrFeatOrNeither setDelegate:self];
	[self setupSpellSubTypeForSpell:spell];
}
-(void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem{
	//NSLog(@"hello");
	if([tabView isEqualTo:damageOrFeatOrNeither]){
		//NSLog(@"spellSubtype changed");
		[self spellSubtypeChanged:nil];
	}
}
-(void)tableViewSelectionDidChange:(NSNotification *)notification{
	if([[notification object] isEqualTo:spellTable]){
		[self areaTypeChanged:nil];
		[self castingTimeChanged:nil];
		[self savingThrowTypeChanged:nil];
		[self spellAffectsChanged:nil];
		[self spellTypeChanged:nil];
		[self xpPressed:nil];
		NSArray *array=[spellController selectedObjects];
		if([array count]==0){
			return;
		}
		NSManagedObject *spell=[array objectAtIndex:0];
		[self setupSpellSubTypeForSpell:spell];
	}else if([[notification object] isEqualTo:classTable]){
		if(![classController canRemove]){
			[addClassButton setEnabled:NO];
			return;
		}
		NSManagedObject *theClass=[[classController selectedObjects] objectAtIndex:0];
		NSArray *spellClasses=[spellClassController arrangedObjects];
		int i;
		[addClassButton setEnabled:YES];
		for(i=0;i<[spellClasses count];i++){
			if([[[spellClasses objectAtIndex:i] valueForKey:@"aClass"] isEqualTo:theClass]){
				[addClassButton setEnabled:NO];
				break;
			}
		}
	}
}
//XP button pressed.
-(IBAction)xpPressed:(id)sender{
	NSArray *array=[spellController selectedObjects];
	if([array count]==0){
		[attackRollRequired setEnabled:NO];
		[paralysesTargets setEnabled:NO];
		[targetsChangeEachRound setEnabled:NO];
		[returnToCharacterScreen setEnabled:NO];
		[spellResistance setEnabled:NO];
		[spellAffects setEnabled:NO];
		[characterTypeAffected setEnabled:NO];
		return;
	}
	NSManagedObject *spell=[array objectAtIndex:0];
	if([[spell valueForKey:@"xp"] boolValue]){
		[customXPBox setEnabled:YES];
		[customXPBox setBackgroundColor:[NSColor whiteColor]];
	}else{
		[customXPBox setBackgroundColor:[NSColor colorWithDeviceRed:0.93
															  green:0.93
															   blue:0.93
															  alpha:1.0]];
		
		[customXPBox setEnabled:NO];
	}
}
@end
